package com.hs.device.charger.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.hs.common.security.utils.SecurityUtils;
import com.hs.communication.common.entity.Charger;
import com.hs.communication.common.entity.ChargerData;
import com.hs.communication.common.entity.UserCharger;
import com.hs.communication.common.entity.vo.ChartData;
import com.hs.communication.common.entity.vo.DayChargingEnergy;
import com.hs.communication.common.entity.vo.DayChargingTime;
import com.hs.communication.common.entity.vo.DeviceVo;
import com.hs.device.charger.entity.dto.HistoryDataDto;
import com.hs.device.charger.mapper.ChargerDataMapper;
import com.hs.device.charger.mapper.ChargerMapper;
import com.hs.device.charger.mapper.DateRangeMapper;
import com.hs.device.charger.mapper.UserChargerMapper;
import com.hs.device.charger.service.ChargerService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ChargerServiceImpl extends MPJBaseServiceImpl<ChargerMapper, Charger> implements ChargerService {

    @Resource
    private ChargerMapper chargerMapper;

    @Resource
    private UserChargerMapper userChargerMapper;

    @Resource
    private ChargerDataMapper chargerDataMapper;

    @Resource
    private DateRangeMapper dateRangeMapper;

    @Override
    public List<Charger> getListByUserId(String status) {
        long userId = SecurityUtils.getUserId();
        MPJLambdaWrapper<Charger> wrapper = new MPJLambdaWrapper<Charger>()
                .selectAll(Charger.class)//查询user表全部字段
                .leftJoin(UserCharger.class, UserCharger::getChargerSn, Charger::getSn)
                .eq(UserCharger::getUserId, userId)
                .orderByAsc(Charger::getSn);
        //如果选了具体的状态比如选了在线,那就只查询在线状态的设备
        if (!status.equals("all")) {
            wrapper.eq(Charger::getStatus, status);
        }

        List<Charger> chargers = chargerMapper.selectJoinList(Charger.class, wrapper);
        return chargers;
    }

    @Override
    public DeviceVo getStatistics(long userId) {
        System.out.println("userId=" + userId);
        // 查询全部设备数量
        Long total = getCountByStatus(userId, null);
        // 查询在线设备数量
        Long online = getCountByStatus(userId, "1");
        // 查询离线设备数量
        Long offline = getCountByStatus(userId, "0");
        // 查询故障设备数量
        Long error = getCountByStatus(userId, "2");

        ArrayList<Long> list = new ArrayList<>();
        list.add(total);
        list.add(online);
        list.add(offline);
        list.add(error);

        List<DayChargingEnergy> dayChargingEnergies = dateRangeMapper.getTotalChargingEnergyByUserId(userId);
        List<String> dates = dayChargingEnergies.stream()
                .map(obj -> obj.getDate().toString())
                .collect(Collectors.toList());

        List<Double> energies = dayChargingEnergies.stream()
                .map(DayChargingEnergy::getEnergy)
                .collect(Collectors.toList());

        ChartData barChartData = ChartData.builder().xAxisData(dates).seriesData(energies).build();


        List<DayChargingTime> dayChargingTimes = dateRangeMapper.getTotalChargingTimeByUserId(userId);

        List<String> dates1 = dayChargingTimes.stream()
                .map(obj -> obj.getDate().toString())
                .collect(Collectors.toList());

        List<Double> times = dayChargingTimes.stream()
                .map(DayChargingTime::getTime)
                .collect(Collectors.toList());

        ChartData lineChartData = ChartData.builder().xAxisData(dates1).seriesData(times).build();

        DeviceVo deviceVo = DeviceVo.builder().counts(list).barChartData(barChartData).lineChartData(lineChartData).build();

        return deviceVo;
    }

    @Override
    public List<String> getSns(long userId) {
        LambdaQueryWrapper<UserCharger> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserCharger::getUserId,userId).orderByAsc(UserCharger::getChargerSn);
        List<UserCharger> list = userChargerMapper.selectList(queryWrapper);
        List<String> sns = list.stream().map(obj -> obj.getChargerSn()).collect(Collectors.toList());
        return sns;
    }

    @Override
    public List<String> getSns() {
        long userId = SecurityUtils.getUserId();
        return this.getSns(userId);
    }

    @Override
    public int updateStatus(Charger charger) {
        LambdaUpdateWrapper<Charger> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(Charger::getStatus, charger.getStatus())
                .set(Charger::getOffOnlineTime, charger.getOffOnlineTime())
                .eq(Charger::getSn, charger.getSn());
        return chargerMapper.update(null, updateWrapper);
    }

    @Override
    public int insert(ChargerData chargerData) {
        return chargerDataMapper.insert(chargerData);
    }


    @Override
    public List<ChargerData> getHistory(HistoryDataDto historyDataDto) {
        LambdaQueryWrapper<ChargerData> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChargerData::getSn,historyDataDto.getSn())
                .between(ChargerData::getReportTime,historyDataDto.getStartDate(),historyDataDto.getEndDate());
        return  chargerDataMapper.selectList(queryWrapper);
    }

    @Override
    public int deleteHistory(List<Long> ids) {
        System.out.println("批量删除");
        return chargerDataMapper.deleteBatchIds(ids);
    }

    // 封装查询方法
    private Long getCountByStatus(long userId, String status) {
        MPJLambdaWrapper<Charger> wrapper = new MPJLambdaWrapper<Charger>()
                .select(Charger::getSn)
                .leftJoin(UserCharger.class, UserCharger::getChargerSn, Charger::getSn)
                .eq(UserCharger::getUserId, userId);

        if (status != null) {
            wrapper.eq(Charger::getStatus, status);
        }

        return chargerMapper.selectJoinCount(wrapper);
    }
}
